<template>
  <div v-loading="loading" class="AddOrUpdate_main add_container">
    <div class="main_main">
      <div v-if="showDetail" class="superPlanning_leftChoose">
        <div class="leftChoose_way">
          <div class="leftChoose_way_name">选择物料</div>
          <div class="leftChoose_way_search">
            <el-input v-model="materialSearch" placeholder="搜索物料编码/名称" clearable @clear="searchMaterial" @keyup.enter.native="searchMaterial" />
          </div>
          <div
            class="leftChoose_way_show"
          >

            <!--            <div v-for="(item,index) in materialList" :key="index" class="leftChoose_way_show_item" @click="chooseMaterial(item)">-->
            <!--                <div class="leftChoose_way_show_item_header">{{ item.materialCode }}</div>-->
            <!--                <div class="leftChoose_way_show_item_name">{{ item.materialName }}</div>-->
            <!--            </div>-->

            <div
              v-for="(item,index) in materialList"
              :key="index"
              draggable="true"
              class="leftChoose_way_show_item"
              @dragstart="dragStart($event,item)"
            >
              <div class="leftChoose_way_show_item_header">{{ item.materialName }}</div>
              <div class="leftChoose_way_show_item_name">{{ item.materialCode }}</div>
            </div>

          </div>
        </div>
        <div class="leftChoose_way leftChoose_way2">
          <div class="leftChoose_way_name">选择工序</div>
          <div class="leftChoose_way_search">
            <el-input v-model="processSearch" placeholder="搜索工序名称" clearable @clear="searchProcess" @keyup.enter.native="searchProcess" />
          </div>
          <div class="leftChoose_way_show">
            <div
              v-for="(item,index) in processList"
              :key="index"
              draggable="true"
              class="leftChoose_way_show_item"
              @click="chooseProcess(item)"
              @dragstart="dragStart($event,item)"
            >
              <div class="leftChoose_way_show_item_header">{{ item.name }}</div>
            </div>
          </div>
        </div>
      </div>
      <div
        id="superPlanning_ID"
        @dragover="e=>e.preventDefault()"
        @drop="handleDrop"
      >
        <butterfly-vue
          v-if="showCanvas"
          ref="superPlanningRef"
          :canvas-data="graphData"
          :canvas-conf="canvasConf"
        />
      </div>

      <div class="superPlanning_rightTop" :class="showDetail?'':'showClass'">

        <div class="superPlanning_rightTop_item">
          <div class="superPlanning_rightTop_item_name">
            <label v-if="showDetail" class="bitian">*</label>工艺要求编码
          </div>
          <div class="superPlanning_rightTop_item_value">
            <CodeRuleInput v-if="showDetail" :band-value.sync="formData.code" table-name="engineering_requirement" column-name="code" :is-edit="formData.id" />
            <div v-else class="show">{{ formData.code }}</div>
          </div>
        </div>
        <div class="superPlanning_rightTop_item">
          <div class="superPlanning_rightTop_item_name">
            <label v-if="showDetail" class="bitian">*</label>版本号
          </div>
          <div class="superPlanning_rightTop_item_value">
            <el-input
              v-if="showDetail"
              v-model="formData.versionCode"
              placeholder="请输入"
              :disabled="!showDetail"
            />
            <div v-else class="show">{{ formData.versionCode }}</div>
          </div>
        </div>
        <div class="superPlanning_rightTop_item">
          <div class="superPlanning_rightTop_item_name">
            <label v-if="showDetail" class="bitian">*</label>计划单状态限制
          </div>
          <div class="superPlanning_rightTop_item_value">
            <el-radio-group v-if="showDetail" v-model="formData.isEqual" :disabled="!showDetail">
              <el-radio label="1">是</el-radio>
              <el-radio label="0">否</el-radio>
            </el-radio-group>
            <div v-else class="show">{{ formData.isEqual=='1'?'是':'否' }}</div>
          </div>
        </div>
      </div>

    </div>
    <div v-if="showDetail" class="main_bottom">
      <!-- <el-button v-if="graphData.nodes.length==0" @click="chooseRootMaterial">选择物料</el-button> -->
      <el-button type="cancel" @click.stop="cancel">取消</el-button>
      <el-button @click.stop="onSubmit('0')">保存</el-button>
      <el-button @click.stop="onSubmit('1')">提交</el-button>
    </div>
  </div>
</template>

<script>
import { ButterflyVue } from 'butterfly-vue'
import MaterialNode from './components/nodes/MaterialNode.vue'
import ProcessNode from './components/nodes/ProcessNode.vue'
import EndpointNode from './components/nodes/EndpointNode.vue'
import { list as getProcessList } from '@/api/engineeringManage/processManage'
import { addOrUpdate, getInfo, getInfoYg } from '@/api/engineeringManage/processRequirementNew'

import { getByTableAndColumn } from '@/api/system/codeRule'
import { mapState } from 'vuex'
import ChooseRootMaterial from './components/nodes/ChooseRootMaterial.vue'
import { list as getMaterial } from '@/api/warehouseManagement/materialInfo'

const _ = require('lodash')
var id = 0
var nodeId = 1000
var edgeId = 0
export default {
  name: 'SuperPlanning',
  components: {
    ButterflyVue
  },
  props: {
    layerid: {},
    id: {},
    showDetail: {}
  },
  data() {
    return {
      dragTempData: undefined, // 拖拽过程中的临时数据（用完及时重置）
      materialSearch: '', // 搜索物料的参数
      materialList: [],
      processSearch: '', // 搜索工序的参数
      loading: false,
      showCanvas: true,
      processList: [], // 所有工序
      pageData: {
        status: 1,
        pageNum: 1,
        pageSize: 9999,
        orderByColumn: 'updateTime',
        isAsc: 'desc',
        searchValue: ''
      },
      formData: {
        id: undefined,
        code: '',
        fileName: '',
        fileRealName: '',
        fileUrl: '',
        remark: undefined,
        isEqual: '0', // 计划单状态限制
        versionCode: '' // 版本号
      },
      canvasConf: {
        disLinkable: true, // 可删除连线
        linkable: true, // 可连线
        draggable: true, // 可拖动
        zoomable: true, // 可放大
        moveable: true, // 可平移
        layout: {
          // type: 'dagreLayout',
          // options: {
          //   rankdir: 'LR',
          //   nodesep: 20,
          //   ranksep: 80,
          //   controlPoints: false
          // }
        },
        theme: {
          edge: {
            shapeType: 'AdvancedBezier',
            arrow: true // 线条默认是否带箭头
          }
        }
      },
      watchData: {},
      graphData: {
        groups: [],
        nodes: [],
        edges: []
      }
    }
  },
  computed: {
    ...mapState('engineeringManage', {
      addProcessData: state => state.addProcessData,
      addMaterialData: state => state.addMaterialData,
      updateNodeData: state => state.updateNodeData,
      deleteNodeData: state => state.deleteNodeData,
      processNodeData: state => state.processNodeData
    })
  },
  watch: {
    updateNodeData: {
      deep: true,
      immediate: true,
      handler() {
        if (this.updateNodeData) {
          this.graphData.nodes.forEach(item => {
            if (item.data.nodeId == this.updateNodeData.nodeId) {
              Object.keys(this.updateNodeData).forEach(key => {
                item.data[key] = JSON.parse(JSON.stringify(this.updateNodeData[key]))
              })
            }
          })
          this.$nextTick(() => {
            console.log(this.graphData)
            this.$store.state.engineeringManage.updateNodeData = undefined
            this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
          })
        }
      }
    },
    deleteNodeData: { // 删除节点数据的回调
      handler() {
        if (this.deleteNodeData) {
          console.log('this.deleteNodeData', this.deleteNodeData)
          console.log('this.graphData', this.graphData)
          const deleteNodeId = this.deleteNodeData.nodeId
          // 删除此节点
          this.graphData.nodes.splice(this.graphData.nodes.findIndex(item => item.data.nodeId == deleteNodeId), 1)

          // Edge线段中，删除相关的线段
          const cacheEdges = this.$deepClone(this.graphData.edges)
          for (const cacheEdge of cacheEdges) {
            if (cacheEdge.targetNode == deleteNodeId || cacheEdge.sourceNode == deleteNodeId) {
              this.graphData.edges.splice(this.graphData.edges.findIndex(item => item.id == cacheEdge.id), 1)
            }
          }

          this.$nextTick(() => {
            this.$store.state.engineeringManage.deleteNodeData = undefined
            this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
          })
        }
      }
    },
    deep: true,
    immediate: true
  },
  mounted() {
    const _this = this
    // this.$nextTick(() => {
    //   this.initDag()
    // })
    // setTimeout(() => {
    //   _this.initDag()
    // }, 1000)
    if (this.showDetail) {
      this.searchMaterial()
      this.searchProcess()
    }
    // this.getProcessList()
    // this.getRuleCode()
    if (this.id) { // 编辑
      // this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
      // id = 999
      this.getInfo()
    } else { // 新增
      // setTimeout(() => {
      //   this.chooseRootMaterial()
      // }, 200)
      //
      this.$store.state.engineeringManage.showDetail = true
      this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
    }
  },
  beforeDestroy() {
    this.$store.dispatch('engineeringManage/changeData', {})
  },
  methods: {
    // 开始拖动
    dragStart(e, item) {
      console.log('dragStart', item)
      console.log('offsetX', e.offsetX)
      console.log('offsetY', e.offsetY)
      console.log('-----------------')
      // 先拿到点击拖动的小手的位置，相对于左上角的位置
      // 记录鼠标位置
      this.dragTempData = {
        type: item.materialName ? 'material' : 'process',
        data: item,
        pos: [e.offsetX, e.offsetY]
      }
    },
    // 放置
    handleDrop(e) {
      e.preventDefault()
      e.stopPropagation()
      console.log('handleDrop', e)
      console.log('handleDrop', e.target.className)
      console.log('offsetX', e.offsetX)
      console.log('offsetY', e.offsetY)
      console.log('clientX', e.clientX)
      console.log('clientY', e.clientY)
      if (this.dragTempData && this.dragTempData.data && this.dragTempData.pos) {
        // 计算node节点要放置的位置
        let defaultPos = [e.offsetX, e.offsetY]
        // 针对于点击拖动的小手的位置，进行偏移
        defaultPos = [e.offsetX - this.dragTempData.pos[0], e.offsetY - this.dragTempData.pos[1]]

        // 2种放置位置分开处理
        // 拖动可能会放置到 butterfly-wrapper 内 ，或者 butterfly-wrapper 外（即 butterfly-gird-canvas）
        if (e.target.className == 'butterfly-wrapper') {
          // 如果在butterfly-wrapper 内 ， offsetX 和 offsetY就是相对的位置，不需要处理可以直接加进去

        }
        if (e.target.className == 'butterfly-gird-canvas') {
          // 如果在butterfly-wrapper 外，需要计算偏移量
          // 通过 class 名称获取元素
          var element = document.getElementsByClassName('butterfly-wrapper')[0]
          // 获取元素的位置信息
          var rect = element.getBoundingClientRect()

          console.log('元素的左上角坐标：', rect.left, rect.top)
          console.log('元素的左上角偏移量：', (rect.left - 245), (rect.top - 67))
          // 如果canvas的位置发生了变化，进行偏移
          // 上下左右分别处理
          // 如果是向左移动了，偏移量为 坐标+（移动后的-初始的245)
          // 如果是向右移动了，偏移量为 坐标+（初始的245-移动后的)
          if (rect.left <= 245) {
            defaultPos[0] = defaultPos[0] + (245 - rect.left)
          } else {
            defaultPos[0] = defaultPos[0] - (rect.left - 245)
          }
          // 如果是向上移动了，偏移量为 坐标+（移动后的-初始的245)
          // 如果是向下移动了，偏移量为 坐标+（初始的245-移动后的)

          if (rect.top <= 67) {
            defaultPos[1] = defaultPos[1] + (67 - rect.top)
          } else {
            defaultPos[1] = defaultPos[1] - (rect.top - 67)
          }
        }
        // todo 未考虑缩放的情况

        console.log('最终落座的位置：', defaultPos)
        if (this.dragTempData.type == 'material') {
          this.chooseMaterial(this.dragTempData.data, defaultPos)
        }
        if (this.dragTempData.type == 'process') {
          this.chooseProcess(this.dragTempData.data, defaultPos)
        }
      }
      this.$nextTick(() => {
        this.dragTempData = undefined
      })
    },

    searchMaterial() { // 搜索物料
      const json = this.$deepClone(this.pageData)
      json.searchValue = this.materialSearch
      getMaterial(json).then(res => {
        res.data.forEach(ele => {
          ele.materialId = ele.id
        })
        this.materialList = res.data
      })
    },
    searchProcess() { // 搜索工序
      const json = this.$deepClone(this.pageData)
      json.searchValue = this.processSearch
      getProcessList(json).then(res => {
        this.processList = res.data
      })
    },
    chooseMaterial(item, pos) { // 左侧栏选择物料
      const newNodeId = id++ + ''

      item.nodeId = newNodeId

      item.requisitionOrReturn = '1'
      item.demandNumber = '1'
      delete item.id

      this.graphData.nodes.push({
        id: newNodeId,
        data: item,
        render: MaterialNode,
        left: pos && pos[0] ? pos[0] : undefined,
        top: pos && pos[1] ? pos[1] : undefined,
        endpoints: [
          {
            id: 'top_material_' + newNodeId,
            orientation: [0, -1],
            pos: [0.5, -0.5]
          },
          {
            id: 'right_material_' + newNodeId,
            orientation: [1, 0],
            pos: [0, 0.5]
          },
          {
            id: 'bottom_material_' + newNodeId,
            orientation: [0, 1],
            pos: [0.5, 0]
          },
          {
            id: 'left_material_' + newNodeId,
            orientation: [-1, 0],
            pos: [0, 0.5]
          }
        ]
      })
    },
    chooseProcess(item, pos) { // 左侧栏选择工序
      let newNodeId = ''

      newNodeId = id++ + ''
      const newEdgeIdElement = this.$deepClone(item)
      newEdgeIdElement.nodeId = newNodeId

      newEdgeIdElement.productBySelf = '1'
      newEdgeIdElement.toInspect = '1'
      newEdgeIdElement.toWms = '1'
      newEdgeIdElement.engineeringProcessId = item.id
      newEdgeIdElement.engineeringProcessName = item.name
      console.log('newEdgeIdElement', newEdgeIdElement)
      this.graphData.nodes.push(
        {
          id: newNodeId,
          data: newEdgeIdElement,
          render: ProcessNode,
          left: pos && pos[0] ? pos[0] : undefined,
          top: pos && pos[1] ? pos[1] : undefined,
          endpoints: [
            {
              id: 'top_process_' + newNodeId,
              orientation: [0, -1],
              pos: [0.5, -0.5]
            },
            {
              id: 'right_process_' + newNodeId,
              orientation: [1, 0],
              pos: [0, 0.5]
            },
            {
              id: 'bottom_process_' + newNodeId,
              orientation: [0, 1],
              pos: [0.5, 0]
            },
            {
              id: 'left_process_' + newNodeId,
              orientation: [-1, 0],
              pos: [0, 0.5]
            }
          ]
        }
      )
    },
    getRuleCode() {
      getByTableAndColumn({ table: 'engineering_requirement', column: 'code' }).then(res => {
        if (res.data && res.data.status === '1') { // 如果有编码规则
          this.$store.state.engineeringManage.isEnable = true
          if (this.id) { // 编辑
            this.$store.state.engineeringManage.isAllowEdit = res.data.allowEdit == '1'
          } else { // 新增
            this.$store.state.engineeringManage.isAllowEdit = false
            this.formData.code = '自动生成'
          }
        } else { // 没有编码规则
          this.$store.state.engineeringManage.isEnable = false
        }
      })
    },
    getInfo() {
      const _this = this
      const getInfoCallback = (res) => {
        this.$store.state.engineeringManage.showDetail = this.showDetail
        Object.keys(this.formData).forEach(key => {
          this.formData[key] = res.data[key]
        })
        this.setData(res.data.data)
        this.$nextTick(() => {
          // 拿到数据后，进行一次自动排版
          _this.$refs.superPlanningRef.canvas.autoLayout('dagreLayout',
            {
              rankdir: 'LR',
              nodesep: 20,
              ranksep: 80,
              controlPoints: false
            }
          )
          setTimeout(() => {
            // 自动排版完，拿到自动排版的位置数据，进行手动排版
            const newData = _this.$refs.superPlanningRef.canvas.getDataMap()
            const cache_graphData = _this.$deepClone(_this.graphData)
            cache_graphData.nodes.forEach(item => {
              const cacheItem = newData.nodes.filter(iitem => iitem.id == item.id)[0]
              item.top = cacheItem.top
              item.left = cacheItem.left
            })

            _this.graphData = cache_graphData

            _this.$store.state.engineeringManage.graphData = _this.$deepClone(_this.graphData)
            this.showCanvas = false
            setTimeout(() => {
              this.showCanvas = true
            }, 1)
          }, 1)
        })
      }

      if (this.$parent.pageId === '银光工艺要求') {
        getInfoYg(this.id).then(res => {
          getInfoCallback(res)
        })
      } else {
        getInfo(this.id).then(res => {
          getInfoCallback(res)
        })
      }
    },
    setData(data) {
      const queue = []
      for (let i = 0; i < data.length; i++) {
        queue.push({ node: data[i], parentId: null })
      }
      while (queue.length > 0) {
        const { node, parentId } = queue.shift()
        nodeId++
        const currentNodeId = nodeId.toString()
        // 给 engineeringProcessId 赋值并删除该属性
        const engineeringProcessId = node.engineeringProcessId
        const engineeringProcessName = node.engineeringProcessName
        delete node.engineeringProcessId
        delete node.engineeringProcessName
        const cacheNode = this.$deepClone(node)
        delete cacheNode.children
        console.log('node', node)
        this.graphData.nodes.push(
          {
            id: currentNodeId,
            data: { ...cacheNode, nodeId: currentNodeId },
            render: MaterialNode,
            endpoints: [
              {
                id: 'top_material_' + currentNodeId,
                orientation: [0, -1],
                pos: [0.5, -0.5]
              },
              {
                id: 'right_material_' + currentNodeId,
                orientation: [1, 0],
                pos: [0, 0.5]
              },
              {
                id: 'bottom_material_' + currentNodeId,
                orientation: [0, 1],
                pos: [0.5, 0]
              },
              {
                id: 'left_material_' + currentNodeId,
                orientation: [-1, 0],
                pos: [0, 0.5]
              }
            ]
          }
        )
        if (parentId) {
          edgeId++
          this.graphData.edges.push(
            {
              id: edgeId.toString(),
              // source: (Number(parentId) + 1) + '',
              // target: currentNodeId,
              targetNode: (Number(parentId) + 1),
              sourceNode: currentNodeId,
              target: 'left_process_' + ((Number(parentId) + 1) + ''),
              source: 'right_material_' + currentNodeId,
              type: 'endpoint'
            }
          )
        }
        if (engineeringProcessId) {
          nodeId++
          const processNodeId = nodeId.toString()
          this.graphData.nodes.push(
            {
              id: processNodeId,
              data: {
                id: processNodeId,
                nodeId: processNodeId,
                engineeringProcessName: engineeringProcessName,
                engineeringProcessId: engineeringProcessId,
                productBySelf: node.productBySelf,
                toInspect: node.toInspect,
                toWms: node.toWms,
                standardWorkTime: node.standardWorkTime,
                workTimePrice: node.workTimePrice,
                unitPriceOfPiecework: node.unitPriceOfPiecework
              },
              render: ProcessNode,
              endpoints: [
                {
                  id: 'top_process_' + processNodeId,
                  orientation: [0, -1],
                  pos: [0.5, -0.5]
                },
                {
                  id: 'right_process_' + processNodeId,
                  orientation: [1, 0],
                  pos: [0, 0.5]
                },
                {
                  id: 'bottom_process_' + processNodeId,
                  orientation: [0, 1],
                  pos: [0.5, 0]
                },
                {
                  id: 'left_process_' + processNodeId,
                  orientation: [-1, 0],
                  pos: [0, 0.5]
                }
              ]
            }
          )
          edgeId++
          this.graphData.edges.push(
            {
              id: edgeId.toString(),
              // source: currentNodeId,
              // target: processNodeId,
              targetNode: currentNodeId,
              sourceNode: processNodeId,
              target: 'left_material_' + currentNodeId,
              source: 'right_process_' + processNodeId,
              type: 'endpoint'
            }
          )
        }
        if (node.children) {
          for (let j = 0; j < node.children.length; j++) {
            queue.push({ node: node.children[j], parentId: currentNodeId })
          }
        }
      }
    },
    onSubmit(num) {
      // console.log('graphData', this.graphData)
      // console.log('this.$refs.superPlanningRef', this.$refs.superPlanningRef)
      // this.$refs.superPlanningRef.redraw()
      if (!this.formData.code) {
        this.$message.warning('工艺编码不能为空')
        return
      }
      if (!this.formData.versionCode) {
        this.$message.warning('版本号不能为空')
        return
      }
      // if (!this.graphData.nodes[0].data.versionCode) {
      //   this.$message.warning(`请点击（${this.graphData.nodes[0].data.materialCode}/${this.graphData.nodes[0].data.materialName}）旁边的编辑按钮，输入版本号`)
      //   return
      // }
      // console.log('this.graphData', this.graphData)
      const data = this.$deepClone(this.graphData)
      const nodes = this.$deepClone(data.nodes)
      const edges = this.$deepClone(data.edges)
      // console.log('nodes', nodes)
      // console.log('edges', edges)
      // 条件判断
      // 1.不能有没有连线的Node
      // 2.最终的父级只能有一个（从节点Edge里面判断，sourceNode没有，targetNode有的只能有一个）
      // 3.不能有两个物料或者两个工序直接相连
      if (nodes.some(item => (edges.filter(item2 => item2.sourceNode == item.id || item2.targetNode == item.id).length == 0))) {
        this.$message.warning('工艺编排连线错误！')
        return
      }
      const cacheNodes = [] // 所有的最终节点
      nodes.forEach(item => {
        if (edges.filter(item2 => item2.targetNode == item.id).length > 0 &&
          edges.filter(item2 => item2.sourceNode == item.id).length == 0) {
          cacheNodes.push(item)
        }
      })
      if (cacheNodes.length != 1 || cacheNodes[0].data.engineeringProcessId) {
        this.$message.warning('工艺编排连线错误！')
        return
      }
      if (edges.some(item => (item.source.includes('_process_') && item.target.includes('_process_')) ||
        (item.source.includes('_material_') && item.target.includes('_material_')))) {
        this.$message.warning('工艺编排连线错误！')
        return
      }

      const cacheNodes2 = [] // 所有的原材料节点
      nodes.forEach(item => {
        if (edges.filter(item2 => item2.targetNode == item.id).length == 0 &&
          edges.filter(item2 => item2.sourceNode == item.id).length == 1) {
          cacheNodes2.push(item)
        }
      })
      if (cacheNodes2.some(item => item.data.engineeringProcessId)) {
        this.$message.warning('工艺编排连线错误！')
        return
      }

      // // console.log('node', nodes)
      const nodeTrees = this.$deepClone(this.buildTree(nodes, edges))
      // console.log('nodeTrees1111111', this.$deepClone(nodeTrees))
      this.mergeChildren(nodeTrees)
      // console.log('nodeTrees222222222', this.$deepClone(nodeTrees))
      if (!nodeTrees || nodeTrees.length == 0) {
        this.$message.warning('工艺要求不能为空')
        return
      }
      const json = this.$deepClone(this.formData)
      json.materialId = nodeTrees[0].materialId
      json.status = num
      json.data = nodeTrees
      console.log('json', json)

      addOrUpdate(json).then(res => {
        this.$message.success('操作成功')
        this.$layer.close(this.layerid)
        this.$parent.getList()
        const allPopover = document.querySelectorAll('.el-popper')
        allPopover.forEach(element => {
          element.style.display = 'none'
        })
      })
    },
    buildTree(nodes, edges) {
      const nodeMap = new Map()
      // 使用节点的 id 创建节点映射
      for (const node of nodes) {
        nodeMap.set(node.id, { ...node.data, children: [] })
      }
      console.log('nodeMap', nodeMap)
      // 构建树结构
      for (const edge of edges) {
        var sourceNode = nodeMap.get(edge.sourceNode + '')
        var targetNode = nodeMap.get(edge.targetNode + '')
        // 如果找到源节点和目标节点，则将目标节点添加为源节点的子节点
        if (sourceNode && targetNode) {
          targetNode.children.push(sourceNode)
          console.log('targetNode', targetNode)
          console.log('sourceNode', sourceNode)
        }
      }
      // 查找根节点
      const rootNodes = nodes.filter((node) => !edges.some((edge) => edge.sourceNode === node.id))
      return rootNodes.map((rootNode) => nodeMap.get(rootNode.id))
    },
    mergeChildren(data) {
      for (let i = 0; i < data.length; i++) {
        // data[i]['nodeKey'] = JSON.parse(JSON.stringify(data[i].id))
        data[i]['nodeKey'] = Date.now() + Number(_.uniqueId())
        delete data[i].id
        if (data[i].children) {
          this.mergeChildren(data[i].children)
          for (let j = 0; j < data[i].children.length; j++) {
            if (!data[i].children[j].materialId) {
              data[i].children = data[i].children.concat(data[i].children[j].children)
              data[i].engineeringProcessName = data[i].children[j].engineeringProcessName
              data[i].engineeringProcessId = data[i].children[j].engineeringProcessId

              data[i].productBySelf = data[i].children[j].productBySelf
              data[i].toInspect = data[i].children[j].toInspect
              data[i].toWms = data[i].children[j].toWms
              data[i].standardWorkTime = data[i].children[j].standardWorkTime
              data[i].workTimePrice = data[i].children[j].workTimePrice
              data[i].unitPriceOfPiecework = data[i].children[j].unitPriceOfPiecework
              data[i].children.splice(j, 1)
              j--
            }
          }
        }
      }
    },
    cancel() {
      // console.log('this.graphData', this.graphData)
      this.$layer.close(this.layerid)// 关闭弹框
      const allPopover = document.querySelectorAll('.el-popper')
      allPopover.forEach(element => {
        element.style.display = 'none'
      })
    },
    getProcessList() {
      getProcessList({ status: 1 }).then(res => {
        // this.processList = res.data
        this.$store.state.engineeringManage.processNodeData = res.data
      })
    },
    chooseRootMaterial() {
      this.$layer.iframe({
        // 弹框
        content: {
          content: ChooseRootMaterial, // 传递的组件对象
          parent: this, // 当前的vue对象
          data: {
            selectedRow: [],
            excludeSelect: []
          } // 当前主物料和当前点击的父级物料不能勾选
        },
        area: ['1320px', '700px'],
        title: '选择物料', // 标题
        shadeClose: false, // 点击遮罩是否关闭
        closeable: false // 是否可关闭
      })
    },
    chooseRootMaterialCallBack(item) {
      const nodeId = id++ + ''
      item.nodeId = nodeId
      item.productBySelf = '1'
      item.toInspect = '1'
      item.toWms = '1'
      item.demandNumber = '1'
      item.isEqual = '0'
      this.graphData.nodes.push(
        {
          id: nodeId,
          data: item,
          render: MaterialNode
        }
      )

      this.$nextTick(() => {
        this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
      })
    },
    findChildNodes(results, nodeId) { // 查找子节点
      results.push(nodeId)
      const cacheEdges = this.$deepClone(this.graphData.edges)
      const childNodes = cacheEdges.filter(item => item.source == nodeId)
      if (childNodes.length > 0) {
        for (const childNode of childNodes) {
          this.findChildNodes(results, childNode.target)
        }
      }
    }

  }
}
</script>

<style lang="less" scoped>
.main_main{
  display: flex;
  background-color: rgba(0,0,0,0.1);
  padding-top:0;
  position: relative;
}
.superPlanning_leftChoose{
  width: 220px;height: 100%;
  background-color: white;
  padding: 10px;font-size: 14px;
  .leftChoose_way{
    border: 1px solid #ECECEC;
    display: flex;flex-direction: column;
    height: 60%;
    .leftChoose_way_name{
      background-color: rgb(79, 174, 255);color: white;
      display: flex;align-items: center;justify-content: center;
      height: 30px;
    }
    .leftChoose_way_search{
      padding: 5px;
      /deep/ .el-input__inner{
        height: 26px !important;line-height: 26px !important;
      }
      /deep/ .el-input__suffix{
        height: 26px !important;line-height: 26px !important;
      }
    }
    .leftChoose_way_show{
      overflow-y: auto;
      height: calc(100% - 66px);font-size: 12px;
      .leftChoose_way_show_item{
        cursor: pointer;
        margin: 0 5px 5px;border: 1px solid #ECECEC;border-radius:  3px;
        .leftChoose_way_show_item_header{
          background-color: rgb(79, 174, 255);color: white;
          display: flex;align-items: center;
          height: 20px;
          padding: 0 5px;
          border-radius: 0 0 3px 3px;
        }
        .leftChoose_way_show_item_name{
          display: flex;align-items: center;
          height: 20px;
          padding: 0 5px;
          background-color: white;
        }
      }
      .leftChoose_way_show_item:hover{
        border: 1px solid rgb(79, 174, 255);
      }
    }
  }
  .leftChoose_way2{
    height: 40%;
    margin-top: 10px;
    .leftChoose_way_name{
      background-color: rgb(29, 198, 142) !important;
    }
    .leftChoose_way_show_item_header{
      height: 30px !important;font-size: 14px !important;
      background-color: rgb(29, 198, 142) !important;
      border-radius: 30px !important;
      padding: 0 15px !important;
    }
    .leftChoose_way_show_item{
      border-radius:  30px !important;overflow: hidden;
      border: 0 !important;
      transform: translate(0, 0);
    }
    .leftChoose_way_show_item:hover{
      .leftChoose_way_show_item_header{
        background-color: rgba(29, 198, 142,0.8) !important;
      }

    }
  }
}
#superPlanning_ID{
  flex: 1;
  position: relative;
  /deep/ .butterfly-svg{
    top: -15px !important;
  }
  /deep/ .butterflie-circle-endpoint{
    width: 10px;
    height: 10px;
  }
}
.superPlanning_rightTop{
  z-index: 1000;
  position: absolute;
  right: 0;
  top: 0;
  width: 200px;
  background-color: white;
  padding: 10px;
  font-size: 12px;
  //border: 1px solid #4FAEFF;
  box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;

  .superPlanning_rightTop_item{
    margin-top: 10px;
    //height: 25px;
    // border-bottom: 1px solid rgb(56, 123, 252);
    .superPlanning_rightTop_item_name{
      width: 120px;
      color: #333333;
      font-size: 12px;
      height: 20px;
    }
    .superPlanning_rightTop_item_value{
      /deep/ .el-input__inner{
        height: 25px;
        line-height: 1;
      }
      .el-radio-group{
        margin-left: 10px;
      }
      /deep/ .el-radio{
        font-size: 12px;
      }
    }
  }
  .superPlanning_rightTop_item:first-child{
    margin-top: 0;
  }
  .superPlanning_rightTop_item:last-child{
    border: 0;
  }

}

.showClass{
  .superPlanning_rightTop_item_name{
    color: #1F51B3 !important;
    font-size: 15px !important;
  }
  .show{
    padding-left: 0;
    height: 25px;display: flex;align-items: center;
    font-size: 15px !important;
  }
  .superPlanning_rightTop_item{
    margin-top: 5px;
  }
}
</style>
